package org.kl.bpm.notice;

import java.util.List;

import org.activiti.engine.RepositoryService;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.el.ExpressionManager;
import org.activiti.engine.impl.persistence.entity.HistoricProcessInstanceEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.lang3.StringUtils;
import org.kl.bf.service.basic.NotifyInfoService;
import org.kl.bf.service.basic.UserService;
import org.kl.bf.utils.ApplicationContextHelper;
import org.kl.bpm.entity.conf.BpmConfNotice;
import org.kl.bpm.entity.conf.BpmMailTemplate;
import org.kl.bpm.service.conf.BpmConfNoticeService;
import org.kl.bpm.utils.AssigneeRuleUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ArrivalNotice {
	private static Logger logger = LoggerFactory.getLogger(ArrivalNotice.class);
	public static final int TYPE_ARRIVAL = 0;
	public static final int TYPE_COMPLETE = 1;
	public static final int TYPE_TIMEOUT = 2;

	public void process(DelegateTask delegateTask) {
		String taskDefinitionKey = delegateTask.getTaskDefinitionKey();
		String processDefinitionId = delegateTask.getProcessDefinitionId();

		List<BpmConfNotice> bpmConfNotices = ApplicationContextHelper.getBean(BpmConfNoticeService.class).findByCodeAndProcessDefinitionId(
				taskDefinitionKey, processDefinitionId);
		ProcessDefinition processDefinition = ApplicationContextHelper.getBean(RepositoryService.class).getProcessDefinition(
				processDefinitionId);

		for (BpmConfNotice bpmConfNotice : bpmConfNotices) {
			if (TYPE_ARRIVAL == bpmConfNotice.getType()) {
				processArrival(delegateTask, bpmConfNotice, processDefinition);
			}
		}
	}

	public void processArrival(DelegateTask delegateTask, BpmConfNotice bpmConfNotice, ProcessDefinition processDefinition) {
		UserService userService = ApplicationContextHelper.getBean(UserService.class);
		NotifyInfoService notifyInfoService = ApplicationContextHelper.getBean(NotifyInfoService.class);

		TaskEntity taskEntity = new TaskEntity();
		taskEntity.setId(delegateTask.getId());
		taskEntity.setName(delegateTask.getName());
		taskEntity.setAssigneeWithoutCascade(userService.getUser(delegateTask.getAssignee()).getTrueName());
		taskEntity.setVariableLocal("initiator", getInitiator(userService, delegateTask));
		taskEntity.setVariableLocal("processDefinition", processDefinition);
		logger.debug("initiator : {}", delegateTask.getVariable("initator"));
		logger.debug("variables : {}", delegateTask.getVariables());

		String receiver = bpmConfNotice.getReceiver();
		BpmMailTemplate bpmMailTemplate = bpmConfNotice.getBpmMailTemplate();
		ExpressionManager expressionManager = Context.getProcessEngineConfiguration().getExpressionManager();
		String to = null;
		String subject = expressionManager.createExpression(bpmMailTemplate.getSubject()).getValue(taskEntity).toString();
		String content = expressionManager.createExpression(bpmMailTemplate.getContent()).getValue(taskEntity).toString();
		if ("任务接收人".equals(receiver)) {
			to = userService.getUser(delegateTask.getAssignee()).getTrueName();
		} else if ("流程发起人".equals(receiver)) {
			to = userService.getUser((String) delegateTask.getVariables().get("initiator")).getTrueName();
			if (StringUtils.isBlank(to)) {
				HistoricProcessInstanceEntity historicProcessInstanceEntity = Context.getCommandContext()
						.getHistoricProcessInstanceEntityManager().findHistoricProcessInstance(delegateTask.getProcessInstanceId());
				to = userService.getUser(historicProcessInstanceEntity.getStartUserId()).getTrueName();
			}
		} else {
			to = AssigneeRuleUtils.getAssignee(receiver);
		}

		try {
			notifyInfoService.sendNotice(to, subject, content);
		} catch (Exception e) {
			logger.info("任务开始提醒邮件发送失败：" + e.getMessage());
			e.printStackTrace();
		}
	}

	public String getInitiator(UserService userService, DelegateTask delegateTask) {
		return userService.getUser((String) delegateTask.getVariables().get("initiator")).getTrueName();
	}
}
